package com.csot.job;

import cn.hutool.core.net.NetUtil;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.StrUtil;
import com.csot.common.utils.DictUtils;
import com.csot.model.*;
import com.jfinal.plugin.activerecord.Db;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.Semaphore;

public class SegmentToIp {

    private static Semaphore semaphore = new Semaphore(1);

    private static Semaphore dcnsemaphore = new Semaphore(1);

    private static Semaphore coarsesemaphore = new Semaphore(1);

    private CitySegment cs = new CitySegment().dao();
    private CityIp ci = new CityIp().dao();

    private DcnCity dc = new DcnCity().dao();

    private DcnIp di = new DcnIp().dao();

    private CoarseSegment coarseSegment = new CoarseSegment().dao();

    private CoarseIp coarseIp = new CoarseIp().dao();

    public void cityToIp() {
        this.cityToIp(null);
    }

    public void dcnToIp() {
        this.dcnToIp(null);
    }

    public void coarseToIp() {
        this.coarseToIp(null);
    }

    public void coarseToIp(String city) {

        int avail = coarsesemaphore.availablePermits();
        if (avail == 0) {
            return;
        }
        try {
            coarsesemaphore.acquire();

            String[] citys = {"sy",
                    "dl",
                    "as",
                    "tl",
                    "bx",
                    "dd",
                    "jz",
                    "fs",
                    "yk",
                    "fx",
                    "ly",
                    "pj",
                    "cy",
                    "hld"};
            if (StrUtil.isNotBlank(city)) {
                citys = new String[]{city};
            }

            for (int j = 0; j < citys.length; j++) {
                List<CoarseSegment> coarseSegmentList = coarseSegment.find("select * from t_coarse_segment where ip_city = ?", citys[j]);
                for (CoarseSegment c : coarseSegmentList) {
                    if (c.getIpEndI() < c.getIpStartI()) {
                        continue;
                    }
                    int ci_count = Db.queryInt("select count(*) from t_coarse_ip where ip_segment_id = ?", c.getId());
                    if (ci_count != c.getIpEndI() - c.getIpStartI() + 1) {
                        Db.tx(() -> {
                            Db.delete("delete from t_coarse_ip where ip_segment_id = ?", c.getId());
                            List<CoarseIp> cityIps = new ArrayList<>();
                            for (long i = c.getIpStartI(); i < c.getIpEndI() + 1; i++) {
                                CoarseIp cityIp = new CoarseIp();
                                cityIp.setIpAddressI(i);
                                cityIp.setIpAddress(NetUtil.longToIpv4(i));
                                cityIp.setIpCity(c.getIpCity());
                                cityIp.setIpUseType(c.getIpUseType());
                                cityIp.setIpSegmentId(c.getId());
                                cityIp.setIpUser(c.getIpUser());
                                cityIp.setIpManagement(c.getIpManagement());
                                cityIp.setIpEquipment(c.getIpEquipment());
                                cityIp.setIpStatus(c.getIpStatus());
                                cityIp.setIpType(c.getIpType());
//                                cityIp.setIpUsername(c.getIpUsername());
//                                cityIp.setBusinessNumber(c.getBusinessNumber());
                                cityIp.setIpGateway(c.getIpGateway());
                                cityIp.setIpProposer(c.getIpProposer());
                                cityIp.setIpApplication(c.getIpApplication());
                                cityIp.setRecordStatus(c.getRecordStatus());
                                cityIp.setRecordType(c.getRecordType());
//                                cityIp.setIpSubnet(c.getIpSubnet());
                                cityIps.add(cityIp);
                            }
                            Db.batchSave(cityIps, 999);
                            return true;
                        });
                    }
                }
            }
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        } finally {
            coarsesemaphore.release();
        }

    }


    public void cityToUse() {
        String[] citys = {"sy",
                "dl",
                "as",
                "tl",
                "bx",
                "dd",
                "jz",
                "fs",
                "yk",
                "fx",
                "ly",
                "pj",
                "cy",
                "hld"};

        for (int j = 0; j < citys.length; j++) {
            List<CitySegment> citySegmentList = cs.find("select * from t_city_segment where ip_city = ?", citys[j]);
            for (CitySegment c : citySegmentList) {
                CityIp cityIp = ci.findFirst("select * from t_city_ip where ip_segment_id = ? limit 1", c.getId());
                if (Objects.nonNull(cityIp) && !c.getIpUseType().equalsIgnoreCase(cityIp.getIpUseType())) {
                    Db.update("update t_city_ip set ip_use_type = ? where ip_segment_id = ?", c.getIpUseType(), c.getId());
                }
            }
        }
    }

    public void cityToIp(String city) {

        int avail = semaphore.availablePermits();
        if (avail == 0) {
            return;
        }
        try {
            semaphore.acquire();

            String[] citys = {"sy",
                    "dl",
                    "as",
                    "tl",
                    "bx",
                    "dd",
                    "jz",
                    "fs",
                    "yk",
                    "fx",
                    "ly",
                    "pj",
                    "cy",
                    "hld"};
            if (StrUtil.isNotBlank(city)) {
                citys = new String[]{city};
            }

            for (int j = 0; j < citys.length; j++) {
                List<CitySegment> citySegmentList = cs.find("select * from t_city_segment where ip_city = ?", citys[j]);
                for (CitySegment c : citySegmentList) {
                    if (c.getIpEndI() < c.getIpStartI()) {
                        continue;
                    }
                    int ci_count = Db.queryInt("select count(*) from t_city_ip where ip_segment_id = ?", c.getId());
                    if (ci_count != c.getIpEndI() - c.getIpStartI() + 1) {
                        Db.tx(() -> {
                            Db.delete("delete from t_city_ip where ip_segment_id = ?", c.getId());
                            List<CityIp> cityIps = new ArrayList<>();
                            for (long i = c.getIpStartI(); i < c.getIpEndI() + 1; i++) {
                                CityIp cityIp = new CityIp();
                                cityIp.setIpAddressI(i);
                                cityIp.setIpAddress(NetUtil.longToIpv4(i));
                                cityIp.setIpCity(c.getIpCity());
                                cityIp.setIpUseType(c.getIpUseType());
                                cityIp.setIpSegmentId(c.getId());
                                cityIp.setIpUser(c.getIpUser());
                                cityIp.setIpManagement(c.getIpManagement());
                                cityIp.setIpEquipment(c.getIpEquipment());
                                cityIp.setIpStatus(c.getIpStatus());
                                cityIp.setIpType(c.getIpType());
                                cityIp.setIpUsername(c.getIpUsername());
                                cityIp.setBusinessNumber(c.getBusinessNumber());
                                cityIp.setIpGateway(c.getIpGateway());
                                cityIp.setIpProposer(c.getIpProposer());
                                cityIp.setIpApplication(c.getIpApplication());
                                cityIp.setRecordStatus(c.getRecordStatus());
                                cityIp.setRecordType(c.getRecordType());
                                cityIp.setIpSubnet(c.getIpSubnet());
                                cityIps.add(cityIp);
                            }
                            Db.batchSave(cityIps, 999);
                            return true;
                        });
                    }
                }
            }
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        } finally {
            semaphore.release();
        }

    }

    public void dcnToUse() {
        String[] citys = {"sy",
                "dl",
                "as",
                "tl",
                "bx",
                "dd",
                "jz",
                "fs",
                "yk",
                "fx",
                "ly",
                "pj",
                "cy",
                "hld"};

        for (int j = 0; j < citys.length; j++) {
            List<DcnCity> dcnCities = dc.find("select * from t_dcn_city where ip_city = ?", citys[j]);
            for (DcnCity c : dcnCities) {
                DcnIp dcnIp = di.findFirst("select * from t_dcn_ip where ip_segment_id = ? limit 1", c.getId());
                if (Objects.nonNull(dcnIp) && !c.getIpUseType().equalsIgnoreCase(dcnIp.getIpUseType())) {
                    Db.update("update t_dcn_ip set ip_use_type = ? where ip_segment_id = ?", c.getIpUseType(), c.getId());
                }
            }
        }
    }

    public void dcnToIp(String city) {

        int avail = dcnsemaphore.availablePermits();
        if (avail == 0) {
            return;
        }
        try {
            dcnsemaphore.acquire();

            String[] citys = {"sy",
                    "dl",
                    "as",
                    "tl",
                    "bx",
                    "dd",
                    "jz",
                    "fs",
                    "yk",
                    "fx",
                    "ly",
                    "pj",
                    "cy",
                    "hld"};
            if (StrUtil.isNotBlank(city)) {
                citys = new String[]{city};
            }

            for (int j = 0; j < citys.length; j++) {
                List<DcnCity> dcnCitieList = dc.find("select * from t_dcn_city where ip_city = ?", citys[j]);
                for (DcnCity c : dcnCitieList) {
                    if (c.getIpEndI() < c.getIpStartI()) {
                        continue;
                    }
                    int ci_count = Db.queryInt("select count(*) from t_dcn_ip where ip_segment_id = ?", c.getId());
                    if (ci_count != c.getIpEndI() - c.getIpStartI() + 1) {
                        Db.tx(() -> {
                            Db.delete("delete from t_dcn_ip where ip_segment_id = ?", c.getId());
                            List<DcnIp> dcnIps = new ArrayList<>();
                            for (long i = c.getIpStartI(); i < c.getIpEndI() + 1; i++) {
                                DcnIp dcnIp = new DcnIp();
                                dcnIp.setIpAddressI(i);
                                dcnIp.setIpAddress(NetUtil.longToIpv4(i));
                                dcnIp.setIpCity(c.getIpCity());
                                dcnIp.setIpUseType(c.getIpUseType());
                                dcnIp.setIpSegmentId(c.getId());
                                dcnIp.setIpUser(c.getIpUser());
                                dcnIp.setIpManagement(c.getIpManagement());
                                dcnIp.setIpStatus(c.getIpStatus());
                                dcnIp.setIpEquipment(c.getDeviceName());
                                dcnIps.add(dcnIp);
                            }
                            Db.batchSave(dcnIps, 999);
                            return true;
                        });
                    }
                }
            }
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        } finally {
            dcnsemaphore.release();
        }

    }

    public void checkCitySegment() {
        String[] citys = {"sy",
                "dl",
                "as",
                "tl",
                "bx",
                "dd",
                "jz",
                "fs",
                "yk",
                "fx",
                "ly",
                "pj",
                "cy",
                "hld"};

        for (int j = 0; j < citys.length; j++) {
            List<CitySegment> citySegmentList = cs.find("select * from t_city_segment where ip_city = ?", citys[j]);
            for (int i = 0; i < citySegmentList.size(); i++) {
                for (int q = i + 1; q < citySegmentList.size(); q++) {
                    CitySegment c1 = citySegmentList.get(i);
                    CitySegment q1 = citySegmentList.get(q);
                    if ((q1.getIpStartI() <= c1.getIpStartI() && c1.getIpStartI() <= q1.getIpEndI())
                            || (q1.getIpStartI() <= c1.getIpEndI() && c1.getIpEndI() <= q1.getIpEndI())
                            || (c1.getIpStartI() <= q1.getIpStartI() && q1.getIpStartI() <= c1.getIpStartI())
                            || (c1.getIpStartI() <= q1.getIpStartI() && q1.getIpStartI() <= c1.getIpStartI())
                    ) {
                        c1.setRemark("error");
                        q1.setRemark("error");
                        c1.update();
                        q1.update();
                    }
                }
            }
        }
    }

    public void checkRecordSegment() {
        this.checkRecordSegment(null);
    }

    public void checkRecordSegment(String city) {


        String[] citys = {"sy",
                "dl",
                "as",
                "tl",
                "bx",
                "dd",
                "jz",
                "fs",
                "yk",
                "fx",
                "ly",
                "pj",
                "cy",
                "hld"};
        if (StrUtil.isNotBlank(city)) {
            citys = new String[]{city};
        }

        RecordSegment rs = new RecordSegment().dao();
        for (String cit : citys) {
            List<RecordSegment> recordSegments = rs.find("select * from t_record_segment where ip_city = ?", cit);
            for (RecordSegment r : recordSegments) {
                Integer a = Db.queryInt("select count(*) from t_city_segment where (ip_start_i <=? and ip_end_i >= ?) or (ip_start_i <=? and ip_end_i >= ?)",
                        r.getIpStartI(), r.getIpStartI(), r.getIpEndI(), r.getIpEndI());
                if (a == 0) {
                    String remark = r.getRemark();
                    if (StrUtil.isNotBlank(remark))
                        remark = remark + "-recorderr";
                    else
                        remark = "recorderr";

                    r.setRemark(remark);
                    r.update();
                }
            }
        }


    }


}
